#include <math.h>
#include "diffuse.h"

void normal(double *buf, cgPoint *p1, cgPoint *p2, cgPoint *p3)
{
    /**
     * A = y1 (z2 - z3) + y2 (z3 - z1) + y3 (z1 - z2)
     * B = z1 (x2 - x3) + z2 (x3 - x1) + z3 (x1 - x2)
     * C = x1 (y2 - y3) + x2 (y3 - y1) + x3 (y1 - y2)
     */
    double l;
    int i;
    buf[0] = p1->c[1] * (p2->c[2] - p3->c[2]) + p2->c[1] * (p3->c[2] - p1->c[2]) + p3->c[1] * (p1->c[2] - p2->c[2]);
    buf[1] = p1->c[2] * (p2->c[0] - p3->c[0]) + p2->c[2] * (p3->c[0] - p1->c[0]) + p3->c[2] * (p1->c[0] - p2->c[0]);
    buf[2] = p1->c[0] * (p2->c[1] - p3->c[1]) + p2->c[0] * (p3->c[1] - p1->c[1]) + p3->c[0] * (p1->c[1] - p2->c[1]);
    l = vec_mod(buf);
    for (i = 0; i < 3; i++)
        buf[i] /= l;
}

double dot_product(double *v1, double *v2)
{
    return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
}

double vec_mod(double *v)
{
    return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
}

double angle_theta(cgPoint *p1, cgPoint *p2, cgPoint *p3, double *light_dir)
{
    double n[3], ca;//, vl[3];
    //int i;
    normal(n, p1, p2, p3);
    //for (i = 0; i < 3; i++)
    //vl[i] = light_pos[i] - p1->c[i];
    ca = dot_product(n, light_dir) / (vec_mod(n) * vec_mod(light_dir));
    return ca;//acos(ca);
}

double calc_diffuse_intens(
    cgPoint *p1, 
    cgPoint *p2, 
    cgPoint *p3, 
    double *light_dir,
    double light_intens,
    double kd
    )
{
    double th = angle_theta(p1, p2, p3, light_dir);
    if (th <= 0)//M_PI_2)
     	return 0;
    //th = -th;
    return (light_intens * kd * th);//cos(th));
}
